<script setup lang="ts">
import type { FormInstance } from '@arco-design/web-vue'
import { Message } from '@arco-design/web-vue'
import { ScheduleJobApi } from '@/apis'
import { useForm } from '@/hooks'
import * as Regexp from '@/utils/regexp'

const emit = defineEmits<{
  (e: 'change'): void
}>()

const visible = ref(false)
const loading = ref(false)
const readonly = ref(true)

const dataId = ref('')
const dataDetail = ref<ScheduleJobApi.ScheduleJobDetailResp>()

const isCreateMode = computed(() => dataId.value === '')
const title = computed(() => (isCreateMode.value ? '创建定时任务' : '修改定时任务'))

const formRef = ref<FormInstance>()

const { form, resetForm } = useForm({
  jobKey: undefined,
  jobName: undefined,
  cron: undefined,
  paramJson: '{}',
  initStrategy: 'DO_NOTHING',
  saveLog: 1,
  status: 1,
  description: undefined,
})
const rules: FormInstance['rules'] = {
  jobKey: [{ required: true, message: '请选择任务' }],
  jobName: [{ required: true, match: Regexp.Name, message: '名称只能含有中文、数字、英文、下划线、短横线，长度为2-32位' }],
  cron: [{ required: true, message: '请输入定时表达式' }],
  initStrategy: [{ required: true, message: '请输入初始化策略' }],
  saveLog: [{ required: true, message: '请输入是否记录日志' }],
  status: [{ required: true, message: '请输入状态' }],
}

const jobBeanList = ref<any[]>([])
onMounted(() => {
  ScheduleJobApi.getJobBeanList().then((data) => {
    jobBeanList.value = data
  })
})

// 查询详情
const getDataDetail = async () => {
  dataDetail.value = await ScheduleJobApi.getDetail(dataId.value)
  for (const key in form) {
    form[key] = dataDetail.value?.[key]
  }
  loading.value = false
}

// 打开详情
const open = async (id: string) => {
  dataId.value = id
  loading.value = true
  visible.value = true
  readonly.value = true
  getDataDetail()
}

// 打开编辑
const edit = async (id: string) => {
  dataId.value = id
  loading.value = true
  visible.value = true
  readonly.value = false
  getDataDetail()
}

// 打开新增
const create = async () => {
  dataId.value = ''
  loading.value = false
  visible.value = true
  readonly.value = false
}

// 保存
const onSave = async () => {
  const isInvalid = await formRef.value?.validate()
  if (isInvalid) {
    return false
  }
  if (isCreateMode.value) {
    await ScheduleJobApi.create(form)
    Message.success('添加成功')
  } else {
    await ScheduleJobApi.update(form, dataId.value)
    Message.success('修改成功')
  }
  emit('change')
  visible.value = false
  return true
}

// 取消
const onCancel = () => {
  readonly.value = true
  for (const key in form) {
    form[key] = dataDetail.value?.[key]
  }
  formRef.value?.clearValidate()
}

// 编辑
const onEdit = () => {
  readonly.value = false
}

// 重置
const reset = () => {
  formRef.value?.resetFields()
  resetForm()
}

// 选择任务
const onJobChange = (jobKey: string) => {
  const jobBean = jobBeanList.value.find(item => item.jobKey === jobKey)
  form.jobKey = jobBean?.jobKey
  form.jobName = jobBean?.jobName
  form.cron = jobBean?.jobCron
  form.paramJson = jobBean?.paramJsonExample
}

const openCronOnlineEdit = () => {
  window.open('https://cron.ciding.cc/', '_blank')
}
defineExpose({ open, edit, create })
</script>

<template>
  <ProFormPanel
    v-model:visible="visible"
    mode="drawer"
    :title="title"
    :loading="loading"
    :footer="isCreateMode"
    @confirm="onSave"
    @close="reset"
  >
    <a-form ref="formRef" layout="vertical" :model="form" :rules :readonly>
      <a-card title="基础信息" class="section">
        <template #extra>
          <ReadonlyEditButton
            v-if="!isCreateMode"
            :readonly="readonly"
            :deleteable="true"
            @edit="onEdit"
            @cancel="onCancel"
            @save="onSave"
          />
        </template>
        <a-row :gutter="28">
          <readonly-form-item label="任务" field="jobKey" :span="24">
            <a-select v-model="form.jobKey" placeholder="请选择任务" allow-clear @change="onJobChange">
              <a-option v-for="job in jobBeanList" :key="job.jobKey" :value="job.jobKey">
                {{ job.jobName }}({{ job.jobKey }})
              </a-option>
            </a-select>
            <template #readonly>
              <span v-if="dataDetail?.jobKey">{{ dataDetail?.jobName }}({{ dataDetail?.jobKey }})</span>
            </template>
          </readonly-form-item>
          <!-- <readonly-form-item label="任务编码" field="jobKey" :span="24">
            <a-input v-model.trim="form.jobKey" placeholder="请输入任务编码" />
          </readonly-form-item> -->
        </a-row>
      </a-card>
      <a-card title="调度配置" class="section">
        <a-row :gutter="28">
          <readonly-form-item label="定时表达式" field="cron" :span="24">
            <a-input v-model.trim="form.cron" placeholder="请输入定时表达式">
              <template #prefix>
                <a-tooltip>
                  <span class="cursor-pointer">  <icon-info-circle /></span>
                  <template #content>
                    <span>格式： * * 1 * * ?</span>
                    <br>
                    <span>含义: 秒 分 时 日 月 星期 年</span>
                  </template>
                </a-tooltip>
              </template>
              <template #suffix>
                <a-button type="text" @click="openCronOnlineEdit">
                  在线编辑
                </a-button>
              </template>
            </a-input>
          </readonly-form-item>
          <readonly-form-item label="初始化策略" field="initStrategy" :span="24">
            <DictSelect v-model="form.initStrategy" code="JobInitStrategyEnum" type="select" />
          </readonly-form-item>
          <readonly-form-item label="参数" field="paramJson" :span="24">
            <a-textarea v-model.trim="form.paramJson" placeholder="请输入任务参数" :max-length="255" auto-size allow-clear show-word-limit />
          </readonly-form-item>
        </a-row>
      </a-card>
      <a-card title="其它配置" class="section" />
      <a-row :gutter="28">
        <readonly-form-item label="记录日志" field="saveLog" :span="12">
          <DictSelect v-model="form.saveLog" code="BooleanEnum" type="boolean" />
        </readonly-form-item>
        <readonly-form-item label="任务状态" field="status" :span="12">
          <DictSelect v-model="form.status" code="CommonStatusEnum" type="status" />
        </readonly-form-item>
        <readonly-form-item label="描述" field="description" :span="24">
          <a-textarea v-model.trim="form.description" placeholder="请输入描述" :max-length="255" show-word-limit />
        </readonly-form-item>
      </a-row>
    </a-form>
  </ProFormPanel>
</template>

<style lang="less" scoped></style>
